package frame;

import frame.util.shiro.UserListener;
import frame.util.shiro.UserRealm;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.SessionListener;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.session.mgt.eis.MemorySessionDAO;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfiguration {

    // 3. shiroFilterFactoryBean
    @Bean
    //@ConditionalOnBean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") SecurityManager securityManager) {
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        bean.setSecurityManager(securityManager);

        //添加shiro内置的过滤器链
        Map<String,String> chain = new LinkedHashMap<>();
        bean.setFilterChainDefinitionMap(chain);
        /*
        anon 无需验证就可以访问
        authc 必须认证了才能访问
        user 必须记住我才能访问 一般不用
        prems 必须拥有某个资源的权限才能访问
        role 必须拥有某个角色才能访问
         */
        chain.put("/now", "anon");
        chain.put("/logout", "logout");
        //chain.put("/web/system/auth/user/index", "roles[admin]");
        chain.put("/web/**", "authc");

        // 设置登陆页面的url
        bean.setLoginUrl("/login");
        bean.setUnauthorizedUrl("/403");

        return bean;
    }
    // 2. DefaultWebSecuritManager
    @Bean
    public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("userRealm") UserRealm realm, @Qualifier("sessionManager") SessionManager sessionManager) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(realm);
        securityManager.setSessionManager(sessionManager);
        return securityManager;
    }

    // 1. Realm
    @Bean
    public UserRealm userRealm() {
        UserRealm userRealm = new UserRealm();
        userRealm.setCacheManager(new MemoryConstrainedCacheManager()); // 开启内存缓存
        return userRealm;
    }

    // 开启权限注解
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("defaultWebSecurityManager") SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }
    // 全部session管理
    @Bean
    public DefaultWebSessionManager sessionManager(@Qualifier("shiroSessionDao") MemorySessionDAO dao, @Qualifier("shiroSessionListener")SessionListener sessionListener) {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        sessionManager.setSessionDAO(dao);
        sessionManager.setSessionListeners(Arrays.asList(new SessionListener[]{sessionListener}));
        return sessionManager;
    }
    @Bean
    public MemorySessionDAO shiroSessionDao() {
        return new MemorySessionDAO();
    }
    @Bean
    public UserListener shiroSessionListener() {
        return new UserListener();
    }
}
